﻿using Coldairarrow.Business.AOP;
using Coldairarrow.Business.Interface;
using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.Entity.DTO;
using Coldairarrow.Util;
using EFCore.Sharding;
using LinqKit;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;

namespace Coldairarrow.Business.Base_Manage
{
    public class Base_JobBusiness : BaseBusiness<Base_Job>, IBase_JobBusiness, ITransientDependency
    {
        public Base_JobBusiness(IDbAccessor db)
            : base(db)
        {
        }

        #region 外部接口

        public async Task<PageResult<Base_Job>> GetDataListAsync(PageInput<ConditionDTO> input)
        {
            var q = GetIQueryable();
            var where = LinqHelper.True<Base_Job>();
            var search = input.Search;

            //筛选
            if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<Base_Job, bool>(
                    ParsingConfig.Default, false, $@"{search.Condition}.Contains(@0)", search.Keyword);
                where = where.And(newWhere);
            }

            return await q.Where(where).GetPageResultAsync(input);
        }

        public async Task<Base_Job> GetTheDataAsync(string id)
        {
            return await GetEntityAsync(id);
        }

        public async Task AddDataAsync(Base_Job data)
        {
            await InsertAsync(data);
        }

        public async Task UpdateDataAsync(Base_Job data)
        {
            await UpdateAsync(data);
        }

        public async Task DeleteDataAsync(List<string> ids)
        {
            await DeleteAsync(ids);
        }

        #endregion
        [AOPTestAttribute]
        public async Task<Base_ColumnStyle[]> GetColumnsAsync(string tabName)
        {
            return await GetColumnsBaseAsync(tabName);
        }

        #region 私有成员

        #endregion

        public string StartJob(List<Base_Job> datas)
        {
            string result = "执行成功";
            Type type = Type.GetType(datas.First().ClassName);
            datas.ForEach(data =>
            {
                if (JobHelper._jobs.ContainsKey(data.ClassName)) throw new Exception($"{data.ClassName}任务已开启，无需重复启动");
                if (type == null) throw new Exception($"{data.ClassName}找不到任务，请检查任务名称是否错误");
                if (type.IsSubclassOf(typeof(IJob_Business))) throw new Exception($"{data.ClassName}此任务未继承IJob_Business基类，请检查");
                // 使用反射创建类的实例
                IJob_Business instance = (IJob_Business)Activator.CreateInstance(type);
                //循环执行任务


                if (data.Unit == "Date")
                {
                    string[] strings = data.StartTime.Split(":");
                    JobHelper.SetDailyJob(instance.Job, Convert.ToInt32(strings[0]), Convert.ToInt32(strings[1]), 0, data.ClassName);
                }
                else
                {
                    JobHelper.SetIntervalJob(instance.Job, data.Unit.ToTimeSpan(data.TimeSpan), data.ClassName);
                }

                data.State = "Y";

            });
            Update(datas);
            return result;
        }

        public string CloseJob(List<Base_Job> datas)
        {
            ConcurrentDictionary<string, Action> jobs = JobHelper._jobs;
            string result = "执行成功";
            datas.ForEach(data =>
            {
                if (!JobHelper._jobs.ContainsKey(data.ClassName)) throw new Exception("此任务未开启，无需关闭");
                JobHelper.RemoveJob(data.ClassName);
                data.State = "N";
            });
            Db.Update<Base_Job>(datas);
            return result;
        }
        public string ExecuteJob(Base_Job data)
        {
            string result = "执行成功";
            Type type = Type.GetType(data.ClassName);
            if (type == null) throw new Exception("找不到任务，请检查任务名称是否错误");
            if (type.IsSubclassOf(typeof(IJob_Business))) throw new Exception("此任务未继承IJob_Business基类，请检查");
            if (data.State == "Y") throw new Exception("此任务循环执行中，需要先关闭才可进行此操作");
            // 使用反射创建类的实例
            IJob_Business instance = (IJob_Business)Activator.CreateInstance(type);
            //立即执行一次执行任务
            instance.Job();
            data.State = "";
            Db.Update<Base_Job>(data);
            return result;
        }

    }
}